package com.lalifa.googledate.util

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.Point
import android.os.Looper
import android.text.Spannable
import android.text.SpannableString
import android.util.DisplayMetrics
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
import com.hjq.permissions.Permission
import com.lalifa.extension.requestPerm
import com.lalifa.googledate.R
import com.lalifa.googledate.util.Tool.Companion.FRIDAY_BIT
import com.lalifa.googledate.util.Tool.Companion.MONDAY_BIT
import com.lalifa.googledate.util.Tool.Companion.SATURDAY_BIT
import com.lalifa.googledate.util.Tool.Companion.SUNDAY_BIT
import com.lalifa.googledate.util.Tool.Companion.THURSDAY_BIT
import com.lalifa.googledate.util.Tool.Companion.TUESDAY_BIT
import com.lalifa.googledate.util.Tool.Companion.WEDNESDAY_BIT
import com.lalifa.utils.SPUtil
import com.lalifa.utils.UIKit.getResources
import org.joda.time.DateTimeConstants
import java.util.ArrayList
import java.util.Calendar
import java.util.Locale

class MUtils {
    companion object {
        @SuppressLint("DiscouragedApi", "InternalInsetResource")
        fun getBar(): Int {
            return getResources().getDimensionPixelSize(
                getResources().getIdentifier(
                    "status_bar_height",
                    "dimen",
                    "android"
                )
            );
        }

        //申请权限
        fun AppCompatActivity.getPerm(callback: (Boolean) -> Unit) {
            requestPerm(
                permissions = {
                    add(Permission.POST_NOTIFICATIONS)
                    add(Permission.READ_CALENDAR)
                    add(Permission.WRITE_CALENDAR)
//                    add(Permission.ACCESS_FINE_LOCATION)
//                    add(Permission.ACCESS_COARSE_LOCATION)
                },
                onGranted = { list, boolean ->
                    callback(boolean)
                }
            )
        }

        fun AppCompatActivity.getDeviceHeight(): Int {
            val display = windowManager.defaultDisplay
            val size = Point()
            display.getRealSize(size)
            val height1 = size.y

            val displayMetrics = DisplayMetrics()
            windowManager.defaultDisplay.getMetrics(displayMetrics)
            val height = displayMetrics.heightPixels
            val width = displayMetrics.widthPixels
            return height1
        }

        fun AppCompatActivity.getDevicewidth(): Int {
            val displayMetrics = DisplayMetrics()
            windowManager.defaultDisplay.getMetrics(displayMetrics)
            val height = displayMetrics.heightPixels
            return displayMetrics.widthPixels
        }

        fun AppCompatActivity.applyFontToMenuItem(mi: MenuItem) {
            val font = ResourcesCompat.getFont(this, R.font.googlesansmed)
            val mNewTitle = SpannableString(mi.title)
            mNewTitle.setSpan(
                CustomTypefaceSpan("", font),
                0,
                mNewTitle.length,
                Spannable.SPAN_INCLUSIVE_INCLUSIVE
            )
            mi.setTitle(mNewTitle)
        }

        @SuppressLint("DiscouragedApi", "InternalInsetResource")
        fun AppCompatActivity.getNavigationHeight(): Int {
            val resources = resources
            val resourceId = resources.getIdentifier(
                "navigation_bar_height",
                "dimen", "android"
            )
            return if (resourceId > 0) {
                resources.getDimensionPixelSize(resourceId)
            } else 0
        }

        @SuppressLint("InternalInsetResource", "DiscouragedApi")
        fun AppCompatActivity.getStatusBarHeight(): Int {
            var result = 0
            val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
            if (resourceId > 0) {
                result = resources.getDimensionPixelSize(resourceId)
            }
            return result
        }
        fun Int.getContrastColor(): Int {
            val y = (299 * Color.red(this) + 587 * Color.green(this) + 114 * Color.blue(this)) / 1000
            return if (y >= 149 && this != Color.BLACK) Color.parseColor(Tool.color) else Color.WHITE
        }

        fun ensureBackgroundThread(callback: () -> Unit) {
            if (Looper.myLooper() == Looper.getMainLooper()) {
                Thread {
                    callback()
                }.start()
            } else {
                callback()
            }
        }

        fun Context.getShortDaysFromBitmask(bitMask: Int): String {
            val dayBits = withFirstDayOfWeekToFront(listOf(MONDAY_BIT,
                TUESDAY_BIT, WEDNESDAY_BIT, THURSDAY_BIT, FRIDAY_BIT, SATURDAY_BIT, SUNDAY_BIT))
            val weekDays = withFirstDayOfWeekToFront(resources.getStringArray(R.array.week_days_short).toList())

            var days = ""
            dayBits.forEachIndexed { index, bit ->
                if (bitMask and bit != 0) {
                    days += "${weekDays[index]}, "
                }
            }

            return days.trim().trimEnd(',')
        }

        private fun <T> Context.withFirstDayOfWeekToFront(weekItems: Collection<T>): ArrayList<T> {
            val firstDayOfWeek = getFirstDayOfWeek()
            if (firstDayOfWeek == DateTimeConstants.MONDAY) {
                return weekItems.toMutableList() as ArrayList<T>
            }

            val firstDayOfWeekIndex = getFirstDayOfWeek() - 1
            val rotatedWeekItems = weekItems.drop(firstDayOfWeekIndex) + weekItems.take(firstDayOfWeekIndex)
            return rotatedWeekItems as ArrayList<T>
        }

        fun getFirstDayOfWeek():Int {
                val defaultFirstDayOfWeek = Calendar.getInstance(Locale.getDefault()).firstDayOfWeek
                return SPUtil.get(Tool.FIRST_DAY_OF_WEEK, getDayOfWeekFromJava(defaultFirstDayOfWeek))
            }
        private fun getDayOfWeekFromJava(dayOfWeek: Int): Int {
            return when (dayOfWeek) {
                Calendar.SUNDAY -> DateTimeConstants.SUNDAY
                Calendar.MONDAY -> DateTimeConstants.MONDAY
                Calendar.TUESDAY -> DateTimeConstants.TUESDAY
                Calendar.WEDNESDAY -> DateTimeConstants.WEDNESDAY
                Calendar.THURSDAY -> DateTimeConstants.THURSDAY
                Calendar.FRIDAY -> DateTimeConstants.FRIDAY
                Calendar.SATURDAY -> DateTimeConstants.SATURDAY
                else -> throw IllegalArgumentException("Invalid day: $dayOfWeek")
            }
        }
    }
}